#include "node_editor_subs.h"
#include "ui_node_editor_subs.h"
#include <QTableWidgetItem>
#include <QHeaderView>
#include <QStandardItemModel>
#include <QEvent>
#include <QMenu>
#include <QAction>
#include <QContextMenuEvent>
#include <QDebug>
#include "../public_opt_subs/mouse_mdle/right_click_blck/TableMenuFilter.h"
#include <QDir>

node_editor_subs::node_editor_subs(QString dir,QWidget *parent) :
    QWidget(parent),
    ui(new Ui::node_editor_subs)
{
    ui->setupUi(this);
    ui->ui_prc->setValue(100);
    // --------------------------------------------
    // 加载表格
    table = new QTableWidgetOperate(256,256,this); //创建默认大小的画布，用于实现对应数量的器件
    table->setScrollSpeed(0.5);
    ui->ui_pages->addTab(table,"node_view"); //创建初始视图
    table_help = new QTableWidgetSave(6,6,this); //! 设置帮助文档
    ui->ui_pages->addTab(table_help,"help_view"); //创建初始视图
    //设置内容填充
    table->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
    table->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
    table->resizeColumnsToContents();
    table->resizeRowsToContents();
    //优化界面
    table->setShowGrid(false);
    table->setEditTriggers(QAbstractItemView::NoEditTriggers);
    // 计算中心单元格的坐标
    int centerRow = table->rowCount() / 2;
    int centerCol = table->columnCount() / 2;

    // 获取中心单元格的项
    QTableWidgetItem* centerItem = table->item(centerRow, centerCol);
    if (!centerItem) {
        // 若中心单元格没有项，就创建一个
        centerItem = new QTableWidgetItem("");
        table->setItem(centerRow, centerCol, centerItem);
    }
    // 滚动到中心单元格
    table->scrollToItem(centerItem, QAbstractItemView::PositionAtCenter);

    //注册动作
    connect(table, &QTableWidget::cellDoubleClicked, this, &node_editor_subs::on_table_double_click);
    connect(table, &QTableWidget::cellClicked, this, &node_editor_subs::on_table_click);
    TableMenuFilter * filter = new TableMenuFilter(table,this);
    table->installEventFilter(filter);
    connect(filter, &TableMenuFilter::move_trig, this, &node_editor_subs::on_menu_move_click);
    connect(filter, &TableMenuFilter::copy_trig, this, &node_editor_subs::on_menu_copy_click);
    connect(filter, &TableMenuFilter::connect_trig, this, &node_editor_subs::on_menu_connect_click);
    connect(filter, &TableMenuFilter::create_trig, this, &node_editor_subs::on_menu_create_click);
    connect(filter, &TableMenuFilter::delete_trig, this, &node_editor_subs::on_menu_delete_click);

    //设置右键菜单的内容
    connect_flag = false;
    move_flag = false;
    copy_flag = false;

    //增加测试器件
//    dev_demo = new device_mdle;
//    dev_demo2 = new device_mdle;
//    ui->ui_pages->addTab(dev_demo,"device");
//    ui->ui_pages->addTab(dev_demo2,"device2");

    //设置字体的颜色
    table->setStyleSheet("QTableWidget::item {"
                           "    color: black;"  // 设置文字颜色为黑色
                           "}");
    // --------------------------------------------
    // 序列化与反序列化目录 
    ui->ui_workdir->setEnabled(false); //关闭编辑，初始时加载目录，后续当状态栏使用，不能手动修改
    if(dir == "") //没有传递类参数
    {
        QString setting_ini = QApplication::applicationDirPath() + "/user_data/setting.ini";
        settings = new QSettings(setting_ini,QSettings::IniFormat);
        work_dir = settings->value("work_dir","").toString(); //加载上次的目录
    } else {
        work_dir = dir;
    }
    if(work_dir != "") //如果存在工作目录
    {
        load_dir(); //! 加载新的目录
    }
}

node_editor_subs::~node_editor_subs()
{
    delete ui;
}

//void node_editor_subs::on_ui_btn_add_clicked()
//{
//    dev_list.append(dev_demo); //增加测试设备
//    dev_demo2->setSite(15,5,21,10);
//    dev_list.append(dev_demo2);

//    //更新视图
//    on_devs_update();
//}
void node_editor_subs::on_dev_update(device_mdle *dev)
{
    ui->ui_pages->setCurrentIndex(1);
    //绘制器件的范围
    QList<int> site = dev->getSite();
    QList<QString> ins = dev->getInputName();
    QList<QString> outs = dev->getOutputName();

    for(int i = site.at(0); i <= site.at(2); i++) //X循环，为列
    {
        for(int j = site.at(1); j <= site.at(3); j++) //Y循环，为行
        {
            if(i > 0 && j > 0)
            {
                //绘制器件范围
                QTableWidgetItem *item = new QTableWidgetItem(""); //初始化未配置的文件
                table->setItem(j, i, item);
                table->item(j,i)->setBackgroundColor(color_dev); //创建器件的底色
                //加载中间信息
                if(i == (site.at(0) + site.at(2))/2)
                {
                    //加载设备名
                    if(j == site.at(1))
                    {
                        table->item(j,i)->setText(dev->getDevName());
                    }
                    //加载设备编号
                    if(j == site.at(1) + 1)
                    {
                        table->item(j,i)->setText(dev->getDevCode());
                    }
                    table->item(j,i)->setBackgroundColor(color_info); //创建中间信息的的底色
                }
                //加载IO
                if(j < site.at(1) + ins.size() * 2 && (j - site.at(1)) % 2 == 1 //绘制IO，2格代表一个IO，且IO存在位置
                && i ==  site.at(0) )
                {
                    table->item(j,i)->setBackgroundColor(color_io); //创建IO信息的的底色
                    table->item(j,i)->setText(ins.at((j-site.at(1))/2)); //设置IO名称
                }
                if(j < site.at(1) + outs.size() * 2 && (j - site.at(1)) % 2 == 1 //绘制IO，2格代表一个IO，且IO存在位置
                && i ==  site.at(2) )
                {
                    table->item(j,i)->setBackgroundColor(color_io); //创建IO信息的的底色
                    table->item(j,i)->setText(outs.at((j-site.at(1))/2)); //设置IO名称
                }
            }

        }
    }
    ui->ui_pages->setCurrentIndex(0);
}

void node_editor_subs::on_devs_update()
{
    table->clear();
    for(int i = 0; i < dev_list.size(); i++)
    {
        on_dev_update(dev_list.at(i));
    }
    on_lins_update(); //更新器件完成后同步更新连线
}

void node_editor_subs::on_lin_update(line_mdle *lin)
{
    ui->ui_pages->setCurrentIndex(1);
    //按照线的起点和终点，规避掉器件占用的单元格，就可以完成连线
    //1. 先确认起点和终点的方向
    QList<int> site = lin->getSite();

    int start_x;
    int start_y = site.at(1);
    bool start_is_out = false;
    if(table->item(site.at(1),site.at(0)-1) != nullptr) //IO左边为器件，则起点为输出
    {
        if(table->item(site.at(1),site.at(0)-1)->backgroundColor() == color_dev)
        {
            //qDebug() << site << "add";
            start_x = site.at(0)+1;
            start_is_out = true;
        }
        else
        {
            //qDebug() << site << "sub";
            start_x = site.at(0)-1;
        }

    }
    else //器件存在边界
    {
        //qDebug() << site << "sub";
        start_x = site.at(0)-1;
    }
    int end_x;
    int end_y = site.at(3);
    bool end_is_out = false;
    if(table->item(site.at(3),site.at(2)-1) != nullptr) //IO左边为器件，则起点为输出
    {
        if(table->item(site.at(3),site.at(2)-1)->backgroundColor() == color_dev)
        {
            end_x = site.at(2)+1;
            end_is_out = true;
        }
        else
        {
            end_x = site.at(2)-1;
        }
    }
    else //器件存在边界，
    {
        end_x = site.at(2)-1;
    }
    // --------------------------------------------
    // 限制连线的类型
    if(end_is_out == start_is_out)
    {
        lin_inout_error = true; //类型相同则报错,结束绘制
        ui->ui_pages->setCurrentIndex(0); //返回显示界面
        return;
    }
    bool allow_connect_logic = true;
    int conenct_out_x,conenct_out_y; //连接输出的地址
    int conenct_in_x,conenct_in_y; //连接输出的地址
    if(end_is_out)
    {
        conenct_out_x = site.at(2);
        conenct_out_y = site.at(3);
        conenct_in_x  = site.at(0);
        conenct_in_y  = site.at(1);
    }
    else
    {
        conenct_out_x = site.at(0);
        conenct_out_y = site.at(1);
        conenct_in_x  = site.at(2);
        conenct_in_y  = site.at(3);
    }
    if(pointInDevices(conenct_out_x,conenct_out_y))
    {
        dev_connect_out = dev_point;
    } else {
        allow_connect_logic = false;
    }
    if(pointInDevices(conenct_in_x,conenct_in_y))
    {
        dev_connect_in  = dev_point;
    } else {
        allow_connect_logic = false;
    }
    int out_index = (conenct_out_y - dev_connect_out->getSite().at(1) + 1)/2;
    int in_index  = (conenct_in_y - dev_connect_in->getSite().at(1) + 1)/2;
    QDEBUG << "allow connect" << allow_connect_logic << out_index << in_index;
    if(allow_connect_logic) //允许连接逻辑
    {
        //直接将信号的连接关系注册到列表
        QMetaObject::Connection conn_out_tx;
        QMetaObject::Connection conn_out_rx;
        connectLineLogic(conn_out_tx,conn_out_rx,out_index,in_index);
        connections_list.append(conn_out_tx);
        connections_list.append(conn_out_rx);
        //连接关系按照奇数和偶数的地址进行缓存，
        //作为线的一个部分可以进行配置
    }
    // --------------------------------------------
    // UI界面的更新
    //对调起点和终点
    int tmp;
    if(start_x > end_x)
    {
        tmp = end_x;
        end_x = start_x;
        start_x = tmp;
        tmp = end_y;
        end_y = start_y;
        start_y = tmp;
    }
    //qDebug() << "line: " << start_x << start_y << end_x << end_y;
    //绘制横线
    for(int i = start_x; i <= end_x; i ++)
    {
        if(i > 0 && (start_y + end_y) / 2 > 0)
        {
            //table->item((start_y + end_y) / 2,i)->setBackgroundColor(color_lin);//连线
            if(table->item((start_y + end_y)/2,i) == nullptr)
            {
                QTableWidgetItem* item = new QTableWidgetItem("");
                table->setItem((start_y + end_y) / 2,i, item);
                table->item((start_y + end_y)/2,i)->setData(Qt::UserRole, "bottom");
                table->item((start_y + end_y) / 2,i)->setBackgroundColor(color_lin);//连线
            }

        }
    }
    //绘制竖线
    if(start_y < end_y)
    {
        for(int j = start_y; j <= (start_y + end_y) / 2; j ++)
        {
            if(j > 0 && start_x > 0)
            {
                int i = start_x; //绘制起点的竖线
                if(table->item(j,i) == nullptr)
                {
                    QTableWidgetItem* item = new QTableWidgetItem("");
                    table->setItem(j,i, item);
                    table->item(j,i)->setData(Qt::UserRole, "bottom");
                    table->item(j,i)->setBackgroundColor(color_lin);//连线
                }
            }
        }
        //绘制竖线
        for(int j = end_y; j >= (start_y + end_y) / 2; j --)
        {
            if(j > 0 && end_x > 0)
            {
                int i = end_x; //绘制起点的竖线
                //table->item((start_y + end_y) / 2,i)->setBackgroundColor(color_lin);//连线
                if(table->item(j,i) == nullptr)
                {
                    QTableWidgetItem* item = new QTableWidgetItem("");
                    table->setItem(j,i, item);
                    table->item(j,i)->setData(Qt::UserRole, "right");
                    table->item(j,i)->setBackgroundColor(color_lin);//连线
                }
            }
        }
    }
    else
    {
        for(int j = start_y; j >= (start_y + end_y) / 2; j--)
        {
            if(j > 0 && start_x > 0)
            {
                int i = start_x; //绘制起点的竖线
                //table->item((start_y + end_y) / 2,i)->setBackgroundColor(color_lin);//连线
                if(table->item(j,i) == nullptr)
                {
                    QTableWidgetItem* item = new QTableWidgetItem("");
                    table->setItem(j,i, item);
                    table->item(j,i)->setData(Qt::UserRole, "left");
                    table->item(j,i)->setBackgroundColor(color_lin);//连线
                }

            }
        }
        //绘制竖线
        for(int j = end_y; j <= (start_y + end_y) / 2; j++)
        {
            if(j > 0 && end_x > 0)
            {
                int i = end_x; //绘制起点的竖线
                //table->item((start_y + end_y) / 2,i)->setBackgroundColor(color_lin);//连线
                if(table->item(j,i) == nullptr)
                {
                    QTableWidgetItem* item = new QTableWidgetItem("");
                    table->setItem(j,i, item);
                    table->item(j,i)->setData(Qt::UserRole, "right");
                    table->item(j,i)->setBackgroundColor(color_lin);//连线s
                }

            }
        }
    }
    table->update();
    ui->ui_pages->setCurrentIndex(0);
}



void node_editor_subs::on_lins_update()
{
    clearAllConnect(); // 删除之前所有的连接关系
    for(int i = 0; i < lin_list.size(); i++) //刷新所有的线束
    {
        lin_inout_error = false; //! 复位错误标志
        on_lin_update(lin_list.at(i));
        if(lin_inout_error) //当前线逻辑错误
        {
            lin_list.removeAt(i); //删除当前元素
            i--;  //调整后的元素地址整体前移
        }
    }
}

bool node_editor_subs::pointInDevice(int x, int y, device_mdle * dev)
{
//    for(int i = 0; i < dev_list.size(); i++)
//    {
        QList<int> site = dev->getSite();

        if(x >= site.at(0)  && x <= site.at(2)
        && y >= site.at(1)  && y <= site.at(3)    )
        {
            dev_point = dev; //记录下点对应的器件
            return true;
        }
        QDEBUG << site << x << y << false;
//    }
    return false;
}
bool node_editor_subs::pointInDevices(int x, int y)
{
    for(int i = 0; i < dev_list.size(); i++)
    {
        if(pointInDevice(x,y,dev_list.at(i)))
        {
            return true;
        }
    }
    return false;
}
bool node_editor_subs::tableIsEmpty(int x, int y)
{
    //判断背景颜色以确认是否可以用于连线
    QTableWidgetItem *item = new QTableWidgetItem(""); //初始化未配置的文件
    table->setItem(y,x, item);
    if(table->item(y, x)->backgroundColor() != color_dev
    && table->item(y, x)->backgroundColor() != color_info
    && table->item(y, x)->backgroundColor() != color_io)
    {
        return true;
    }
    else
    {
        return false;
    }

}

void node_editor_subs::clearFailLine()
{
    int i = 0;
    while(i < lin_list.size()) //判断所有的线束连接点是否正常
    {
        QList<int> site = lin_list.at(i)->getSite();
        if(pointInDevices(site.at(0),site.at(1))
        && pointInDevices(site.at(2),site.at(3)))
        {
            qDebug() << __LINE__ << "line valid" << i <<  site;
            i ++;
        }
        else //未连接到器件的线进行删除
        {
            lin_list.removeAt(i);
            qDebug() << __LINE__ << "line remove" << i <<  site;
        }
        ui->ui_prc->setValue(i / 100);
    }
    ui->ui_prc->setValue(100);
}

void node_editor_subs::connectLineLogic(QMetaObject::Connection & conn_out_tx,
                                        QMetaObject::Connection & conn_out_rx,
                                        int out_index, int in_index)
{
    //利用内置的宏进行IO的双向连接，总线默认都是双向端口，
    //后续根据需求，可以通过配置总线的属性关闭掉某个方向的连接
    CONNECT_DEVS_INOUT(conn_out_tx,conn_out_rx,
                       dev_connect_out,dev_connect_in,
                       out_index,in_index);

    QDEBUG << "connect" << conn_out_tx << conn_out_rx << out_index << in_index;
}

void node_editor_subs::clearAllConnect()
{
    qDebug() << __LINE__ << "clearAllConnect" << connections_list.size();
    for (auto& conn : connections_list) {
        QObject::disconnect(conn);  // 断开单个连接
    }
    connections_list.clear();  // 清空列表
}

void node_editor_subs::save()
{
    //判断路径为空
    if (work_dir == "")
    {
        // 打开目录选择对话框
        QString directory = QFileDialog::getExistingDirectory(
            this,
            "选择目录",
            QDir::homePath(),
            QFileDialog::ShowDirsOnly
        );

        // 如果用户选择了目录，则显示路径
        if (directory.isEmpty()) {
            return; //路径选择失败
        }
        work_dir = directory;
    }
    //将器件缓存至目标目录
    QDir dir(work_dir);

    if (dir.exists()) {
        qDebug() << "node_editor_subs work_dir is ok";
    } else {
        if (dir.mkpath(work_dir)) {
            QMessageBox::information(this, "成功", QString("已成功创建目录:\n%1").arg(work_dir));
        } else {
            QMessageBox::critical(this, "错误", QString("无法创建目录:\n%1").arg(work_dir));
        }
    }
    //轮询缓存所有器件
    QDir dir_dev(work_dir+"/dev_list");
    QDir dir_lin(work_dir+"/lin_list");
    dir_dev.removeRecursively();
    dir_lin.removeRecursively();
    dir.mkpath("dev_list");
    for(int i = 0; i < dev_list.size();i++)
    {
        QString dev_file = work_dir + "/dev_list/" + QString::number(i) + ".csv";

        dev_list.at(i)->save(dev_file); //轮询缓存所有的器件
        qDebug() << __LINE__ << "device line" << dev_file;
    }
    dir.mkpath("lin_list");
    for (int i = 0; i < lin_list.size();i++)
    {

        QString lin_file = work_dir + "/lin_list/" + QString::number(i) + ".csv";
        lin_list.at(i)->save(lin_file); //轮询缓存所有的器件
        qDebug() << __LINE__ << "save line" << lin_file ;
    }
}

void node_editor_subs::load() //获取目录
{
    //判断路径为空
    if(1) //加载模式默认加载新的地址
    {
        // 打开目录选择对话框
        QString directory = QFileDialog::getExistingDirectory(
            this,
            "选择目录",
            QDir::homePath(),
            QFileDialog::ShowDirsOnly
        );

        // 如果用户选择了目录，则显示路径
        if (directory.isEmpty()) {
            return; //路径选择失败
        }
        work_dir = directory;
    }
    //将器件缓存至目标目录
    QDir dir(work_dir);
    if (dir.exists()) {
        qDebug() << "node_editor_subs work_dir is ok";
    } else {
        if (dir.mkpath(work_dir)) {
            QMessageBox::information(this, "成功", QString("已成功创建目录:\n%1").arg(work_dir));
        } else {
            QMessageBox::critical(this, "错误", QString("无法创建目录:\n%1").arg(work_dir));
        }
    }
    settings->setValue("work_dir",work_dir); //更新到永久变量
    load_dir();
}

void node_editor_subs::load_dir() //获取目录并创建器件
{
    ui->ui_workdir->setText(work_dir);
    //轮询缓存所有器件
    dev_list.clear();
    // 获取所有文件（不包括目录）
    QStringList nameFilters;
    nameFilters << "*.csv"; // 匹配所有带后缀的文件
    QDir dir_dev(work_dir+"/dev_list");
    QStringList files = dir_dev.entryList(
        nameFilters,
        QDir::Files | QDir::NoDotAndDotDot,
        QDir::Name
    );
    for(int i = 0; i < files.size(); i++)
    {
        QString dev_csv = work_dir+"/dev_list/" + files.at(i);
        dev_new = new device_mdle;
        dev_new->load(dev_csv);
        QString dev_name = dev_new->getDevName();
        bool create_flag = false;
        for(int j = 0; j < select_list.count(); j++)
            {
                if(dev_name == select_list.at(j))
                {
                    switch(j) //自动匹配对应的类创建
                    {
                        DEVICE_LIST_SET
                    }
                    create_flag = true;
                }
            }
        if(create_flag)
        {
            dev_new->load(dev_csv); //第二次加载到子类
            dev_list.append(dev_new);
        }

    }
    //加载所有的线束
    lin_list.clear();
    // 获取所有文件（不包括目录）
    QDir dir_lin(work_dir+"/lin_list");
    QStringList files_lin = dir_lin.entryList(
        nameFilters,
        QDir::Files | QDir::NoDotAndDotDot,
        QDir::Name
    );
    for(int i = 0; i < files_lin.size(); i++)
    {
        QString lin_csv = work_dir+"/lin_list/" + files_lin.at(i);
        lin_new = new line_mdle;
        lin_new->load(lin_csv);
        lin_list.append(lin_new); //完成文件的缓存
        //qDebug() << "line site" << lin_new->getSite();
    }
    on_devs_update();
    on_lins_update();
}

void node_editor_subs::on_table_double_click(int row, int column)
{
    qDebug() << __FILE__ << __LINE__ << "double click" << row << column;
    on_table_click(row,column); //双击前先执行一次单击的逻辑
    if(pointInDevice(column,row,dev_sel)) //判断存在器件
    {
        dev_sel->show();
    }
}

void node_editor_subs::on_table_click(int row, int column)
{

    //qDebug() << "site" << row << column << " copy: " <<copy_flag << " connect:" << connect_flag;
    if(ui->ui_prc->value() != 100) // 上次操作未完成
    {
        return;
    }
    //模拟单击选中器件
    for(int i = 0; i < dev_list.size(); i++)
    {
        table->setUpdatesEnabled(false);
        QList<int> site = dev_list.at(i)->getSite();
        if(row >= site.at(1) && row <= site.at(3)
        && column >= site.at(0) && column <= site.at(2)) //发现对应的器件
        {
            table->item(site.at(1), site.at(0))->setBackgroundColor(color_sel); //创建选中底色
            table->item(site.at(3), site.at(2))->setBackgroundColor(color_sel); //创建选中底色
            table->item(site.at(3), site.at(0))->setBackgroundColor(color_sel); //创建选中底色
            table->item(site.at(1), site.at(2))->setBackgroundColor(color_sel); //创建选中底色
            //记录选中的器件
            dev_sel = dev_list.at(i);
            move_flag = false; //当移动状态点击器件会停止移动
        }
        else
        {
            table->item(site.at(1), site.at(0))->setBackgroundColor(color_dev); //器件外围底色
            table->item(site.at(3), site.at(2))->setBackgroundColor(color_dev); //器件外围底色
            table->item(site.at(3), site.at(0))->setBackgroundColor(color_dev); //器件外围底色
            table->item(site.at(1), site.at(2))->setBackgroundColor(color_dev); //器件外围底色

        }
        // 恢复UI更新并一次性刷新
        table->setUpdatesEnabled(true);
        table->viewport()->update(); // 强制一次刷新s
    }
    if(move_flag) //处于移动状态中更新选中的位置
    {
        QList<int> site = dev_sel->getSite();
        int x_len = site.at(2) - site.at(0); //
        int y_len = site.at(3) - site.at(1); //
        // --------------------------------------------
        // 移动线位置
        //计算偏移角度
        int x_offset = column - x_len - site.at(0);
        int y_offset = row - y_len  - site.at(1);
        // --------------------------------------------
        // 移动连线的位置
        for(int i = 0; i < lin_list.size(); i ++)
        {
            QList<int> lin_site = lin_list.at(i)->getSite();
            if(pointInDevice(lin_site.at(0),lin_site.at(1) ,dev_sel))
            {
                lin_list.at(i)->setSite( lin_site.at(0) + x_offset,lin_site.at(1)+y_offset,lin_site.at(2),lin_site.at(3));
                on_lin_update(lin_list.at(i));
            }
            else if(pointInDevice(lin_site.at(2),lin_site.at(3) ,dev_sel))
            {
                lin_list.at(i)->setSite( lin_site.at(0) ,lin_site.at(1),lin_site.at(2)+ x_offset,lin_site.at(3)+y_offset);
                on_lin_update(lin_list.at(i));
            }

            ui->ui_prc->setValue(i / 100);
        }
        // --------------------------------------------
        // 移动器件位置
        if(column > x_len && row > y_len) //坐标合理时更新地址
        {
            dev_sel->setSite(column-x_len, row - y_len ,column,row);
            on_devs_update();
            //on_dev_update(dev_new); //只能全部刷新
        }
    }
    if(connect_flag)
    {
        //qDebug() << "connect" << connect_flag << row << column ;
        if(table->item(row,column) != nullptr)
        {
            if(table->item(row,column)->backgroundColor() == color_io)
            {
                //从起点和终点之间绘制一个连接线
                QString name_first = lin_sel->getName();
                lin_sel->setName(name_first + "X" + QString::number(column) + "Y" + QString::number(row)); //加载名字
                QList<int> site = lin_sel->getSite();
                lin_sel->setSite(site.at(0),site.at(1),column,row); //设置终点IO
                //on_lin_update(lin_sel); //更新选中的连线
                //注册写入连线
                lin_list.append(lin_sel); //注册当前线束
                on_lins_update();
                connect_flag = false; //关闭连线
                this->setCursor(Qt::ArrowCursor);
            }
            else //取消连线
            {
                connect_flag = false; //关闭连线
                this->setCursor(Qt::ArrowCursor);
            }
        }
    }
    if(copy_flag)
    {
        dev_new = new device_mdle;
        dev_new->setDate(dev_sel->getDate()); //复制设备信息
        //刷新设备位置
        //ui->ui_pages->addTab(dev_new,"new");
        QList<int> site = dev_new->getSite();
        int x_len = site.at(2) - site.at(0); //
        int y_len = site.at(3) - site.at(1); //

        if(column > x_len && row > y_len) //坐标合理时更新地址
        {
            dev_new->setSite(column-x_len, row - y_len ,column,row);
            dev_list.append(dev_new);
            on_dev_update(dev_new);
            //on_devs_update();
        }
        copy_flag = false;
    }
    ui->ui_prc->setValue(100);

}

void node_editor_subs::on_menu_move_click(int row, int column)
{
    //移动器件
    on_table_click(row-1,column);
    move_flag = true;
}

void node_editor_subs::on_menu_connect_click(int row, int column)
{
    //连接IO
    move_flag = false; //关闭移动
    on_table_click(row,column); //先选中器件
    if(table->item(row,column) != nullptr && row > 4 && column > 4) //起点错误，不连接
    {
        if(table->item(row,column)->backgroundColor() == color_io)
        {
            connect_flag = true;
            //设置起点坐标
            lin_sel = new line_mdle; //创建线
            lin_sel->setName( "X" + QString::number(column) + "Y" + QString::number(row)); //加载名字
            lin_sel->setSite(column,row,0,0); //设置起点在器件中的位置
            this->setCursor(Qt::CrossCursor); //设置鼠标进入连线形状
        }
    } else {
        qDebug() << __LINE__ << "on_menu_connect_click" << row << column << connect_flag;
    }

}

void node_editor_subs::on_menu_copy_click(int row, int column)
{
    move_flag = false; //关闭移动
    on_table_click(row,column); //先选中器件
    copy_flag = true;
}

void node_editor_subs::on_menu_create_click(int row, int column)
{
    ui->ui_pages->setCurrentIndex(1);
    //创建默认的器件
    u_device_select = new device_select(nullptr,select_list);
    u_device_select->show();
    QStringList info_sel = u_device_select->exec();
    bool sel_right = false;
    qDebug() << __FILE__ << __LINE__ << info_sel << "foreach" << select_list;
    for(int i = 0; i < select_list.count(); i++)
    {
        if(info_sel.at(0) == select_list.at(i))
        {
            sel_right = true; //选中设备
            switch(i) //自动匹配对应的类创建
            {
                DEVICE_LIST_SET
            }
            qDebug() << __FILE__ << __LINE__ << sel_right << i;
        }
    }

    if(!sel_right) //器件类型错误
    {
        return;
    }
    dev_new->setWindowTitle(info_sel.at(0));
    //更新器件的位置
    QList <int> size; //设置大小
    size = dev_new->getSize();
    dev_new->setSite(column,row,column + size.at(0), row + size.at(1));
    dev_list.append(dev_new);
    on_devs_update(); //更新视图
    ui->ui_pages->setCurrentIndex(0);
}

void node_editor_subs::on_menu_delete_click(int row, int column)
{
    for(int i = 0; i < dev_list.size(); i++)
    {
        if(pointInDevice(column,row,dev_list.at(i)))
        {
            dev_list.removeAt(i); //删除对应的器件
            break; //终止寻找
        }
    }
    //清除多余的线束
    clearFailLine();
    qDebug() << __LINE__ << "line resever" << lin_list.size();
    on_devs_update();

}



